package org.alex.farouq.exam.model.question;



import java.io.IOException;

import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.alex.farouq.exam.model.question.choice.CorrectChoice;
import org.alex.farouq.exam.model.question.choice.WrongChoice;
import org.alex.farouq.exam.model.question.mark.Mark;
import org.alex.farouq.exam.model.question.style.ChoiceListingStyle;
import org.alex.farouq.exam.model.question.style.QuestionListingStyle;
import org.alex.farouq.exam.model.question.type.QuestionType;
import org.alex.farouq.exam.model.question.type.SubQuestionType;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;


/**
 * 
 * @author Ahmed Kotb
 * @email eng.ahmedkotb@gmail.com
 * @since 14-Nov-2011
 *
 */
public class QuestionFactory extends DefaultHandler{
	private Question question = null;
	MultipleChoice multipleChoice;
	private SubQuestion tempSubQuestion=null;
	private ArrayList<SubQuestion> subQuestions;
	private ArrayList<CorrectChoice> correctChoices;
	private ArrayList<WrongChoice> wrongChoices;
	private String tempVal;
	boolean questionType = true;
	
	public QuestionFactory(){
		subQuestions = new ArrayList<SubQuestion>();
	}
	
	public Question readQuestionAtPath(String path){
		question = null;
		tempSubQuestion = null;
		subQuestions = new ArrayList<SubQuestion>();
		questionType = true;

      //get a factory
		SAXParserFactory spf = SAXParserFactory.newInstance();
		try {
		
			//get a new instance of parser
			SAXParser sp = spf.newSAXParser();
			
			//parse the file and also register this class for call backs
			sp.parse(path, this);
			
		}catch(SAXException se) {
			se.printStackTrace();
		}catch(ParserConfigurationException pce) {
			pce.printStackTrace();
		}catch (IOException ie) {
			ie.printStackTrace();
		}
		return question;
	}
	
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		//reset
		tempVal = "";
		if(qName.equalsIgnoreCase("SubQuestion")) {
			//create a new instance of employee
			tempSubQuestion = new SubQuestion();
		}
	}
	
	public void characters(char[] ch, int start, int length) throws SAXException {
		tempVal = new String(ch,start,length);
	}
	

	public void endElement(String uri, String localName, String qName) throws SAXException {

		if(questionType) {
			//add it to the list
			int typeId = Integer.parseInt(tempVal);
			switch(typeId){
			case 1:
				question = new MultipleChoice();
				break;
			default:
				break;
			}			
			question.setQuestionType(new QuestionType(typeId));
			questionType = false;
		}
		else if (qName.equalsIgnoreCase("ChoiceListingStyle")) {
			question.setChoiceListingStyle(new ChoiceListingStyle(Integer.parseInt(tempVal)));
		}
		else if (qName.equalsIgnoreCase("QuestionListingStyle")) {
			question.setQuestionListingStyle(new QuestionListingStyle(Integer.parseInt(tempVal)));
		}
		else if(question !=null){
			switch (question.getQuestionType().getTypeId()) {
			case 1:
				if(qName.equalsIgnoreCase("Header")){
					multipleChoice=(MultipleChoice)question;
					multipleChoice.setQuestionHeader(new QuestionHeader(tempVal));
				}
				else if(qName.equalsIgnoreCase("Text")){
					correctChoices = new ArrayList<CorrectChoice>();
					wrongChoices = new ArrayList<WrongChoice>();
					tempSubQuestion.setText(new SubQuestionText(tempVal));
				}
				else if(qName.equalsIgnoreCase("Type")){
					tempSubQuestion.setType(new SubQuestionType(Integer.parseInt(tempVal)));
				}
				else if(qName.equalsIgnoreCase("Mark")){
					tempSubQuestion.setMark(new Mark(Float.parseFloat(tempVal)));
				}
				else if(qName.equalsIgnoreCase("CorrectChoice")){
					correctChoices.add(new CorrectChoice(tempVal));
				}
				else if(qName.equalsIgnoreCase("WrongChoice")){
					wrongChoices.add(new WrongChoice(tempVal));
				}
				else if(qName.equalsIgnoreCase("SubQuestion")){
					tempSubQuestion.setCorrectChoices(correctChoices);
					tempSubQuestion.setWrongChoices(wrongChoices);
					subQuestions.add(tempSubQuestion);
				}
				break;

			default:
				break;
			}
		}
		
	}
	
	public void endDocument (){
		switch (question.getQuestionType().getTypeId()) {
		case 1:
			multipleChoice.setSubQuestions(subQuestions);
			question=multipleChoice;
			break;
		default:
			break;
		}
	}
	/*
	public static void main(String[] args) {
		Question ques= new QuestionFactory().createQuestion("Question 1.xml");
		MultipleChoice multi=(MultipleChoice)ques;
		System.out.println(multi.getQuestionType().getTypeId());
		System.out.println(multi.getSubQuestions().get(1).getCorrectChoices().get(0).getText());
	}
	*/
}